import os,sys,random,pygame,math
from pygame.locals import *
import cPickle as pickle

import screen,particles

def load_image(name,colorkey):
    fullname = os.path.join('data','pictures',name)
    i=pygame.image.load(fullname)
    if colorkey==0:
        colorkey=None
    if colorkey is not None:
        if colorkey is -1:
            colorkey = i.get_at((0,0))
        i.set_colorkey(colorkey, RLEACCEL)
    return i.convert()

class Player:
    def __init__(self):
        self.image = load_image('player.png',-1)
        self.rect = self.image.get_rect(topleft = (0,0))

        self.alive = 1

        self.speed = 5
        self.jump_force_beginning = 7
        self.max_jump_force = 30
        self.jump_force = 0
        self.jump_force_charge = .05
        self.jumping = 0

        self.falling = 0
        self.old_falling = 0

        self.gravity = 9.8
        self.gravity_mult = 120
        self.falling_velocity = 0
        self.terminal_velocity = self.gravity*2
        self.falling_speed = 0
        self.falling = 0

        self.alive = 1
        self.direction = 'Right'
        self.immobile = 0
        self.particles = []

        
    def jump_bar(self):
        pass

    def start_pos(self,spot):
        self.alive = 1
        self.fall_speed = 0
        self.falling = 1
        self.jumping = 0
        self.rect = self.image.get_rect(center = spot)

    def update(self,underlay,worldrect):
        
        if self.falling_speed < 0:
            self.gravity_move()
            self.check_head(underlay,worldrect)
            self.falling = 1
        elif self.check_floor(underlay,worldrect) == 1:
            self.gravity_move()
            self.falling = 1
        else:
            self.falling_speed = 0
            self.falling_velocity = 0
            self.falling = 0

        if pygame.key.get_pressed()[K_LEFT] and self.immobile == 0:
            self.direction = 'Left'
            self.move_left(underlay,worldrect)
        if pygame.key.get_pressed()[K_RIGHT] and self.immobile == 0:
            self.direction = 'Right'
            self.move_right(underlay,worldrect)
        if pygame.key.get_pressed()[K_UP] and self.falling == 0:
            self.jumping = 1
            self.jump(underlay,worldrect)
            self.jump_force = self.jump_force_beginning
            
        if pygame.key.get_pressed()[K_DOWN] and self.falling == 0:
            print self.jump_force*100
            self.jumping = 1
            self.immobile = 1
            self.jump_force += self.jump_force_charge
            if self.jump_force >= self.max_jump_force:
                self.jump_force = self.max_jump_force
        if pygame.key.get_pressed()[K_DOWN]==False and self.jumping == 1:
            self.jump(underlay,worldrect)
            self.jump_force = self.jump_force_beginning
            self.jumping = 0
            self.immobile = 0

        self.check_jump()
            
        if self.direction == 'Right':
            screen.screen.blit(self.image,self.rect)
        elif self.direction == 'Left':
            screen.screen.blit(pygame.transform.flip(self.image,True,False),self.rect)

        x = 0
        for item in self.particles:
            item.update()
            if item.counter <= 0:
                del self.particles[x]
            else:
                x+=1

    def check_jump(self):
        if self.falling == 0 and self.old_falling == 1:
            self.particles.append(particles.PlayerLanding((self.rect.center[0],self.rect.bottom)))

        self.old_falling = self.falling

    def gravity_move(self):
        self.falling_speed += self.falling_velocity
        self.falling_velocity += self.gravity/self.gravity_mult
        if self.falling_speed >= self.terminal_velocity:
            self.falling_speed = self.terminal_velocity
            self.falling_velocity = 0
        move = (0,self.falling_speed)
        self.rect=self.rect.move(move)

    def check_head(self,underlay,worldrect):
        force = 0
        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.topleft[0]+(self.speed-1),
                                     abs(worldrect.topleft[1])+self.rect.topleft[1]))
        except:
            color = (0,0,123,255)
        if color == (0,0,0,255):
            force = 1
            self.force_move_down(underlay,worldrect)
            self.falling_speed = self.gravity/self.gravity_mult
        if color == (255,0,0,255):
            self.die()
            return 0
            
        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.topright[0]-(self.speed-1),
                                     abs(worldrect.topleft[1])+self.rect.topright[1]))
        except:
            color = (0,0,123,255)
        if color == (0,0,0,255):
            force = 1
            self.force_move_down(underlay,worldrect)
            self.falling_speed = self.gravity/self.gravity_mult
        if color == (255,0,0,255):
            self.die()
            return 0
        if force == 1:
            self.particles.append(particles.PlayerLanding((self.rect.center[0],self.rect.top)))

    def force_move_down(self,underlay,worldrect):
        moving = 1
        movingleft = 1
        movingright = 1
        while moving==1:
            try:
                color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.topleft[0]+(self.speed-1),
                                       abs(worldrect.topleft[1])+self.rect.topleft[1]))
            except:
                print 'Couldnt get color'
                color = (0,0,123,255)
            if color == (0,0,0,255):
                try:
                    color2=underlay.get_at((abs(worldrect.topleft[0])+self.rect.topleft[0]+(self.speed-1),
                                           abs(worldrect.topleft[1])+self.rect.topleft[1]+1))
                except:
                    print 'Couldnt get color 2'
                    color2 = (0,0,123,255)
                if color2 == (0,0,0,255):
                    self.rect = self.rect.move((0,1))
                else:
                    movingleft = 0
            else:
                movingleft = 0

            try:
                color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.topright[0]-(self.speed-1),
                                       abs(worldrect.topleft[1])+self.rect.topright[1]))
            except:
                print 'Couldnt get color'
                color = (0,0,123,255)
            if color == (0,0,0,255):
                try:
                    color2=underlay.get_at((abs(worldrect.topleft[0])+self.rect.topright[0]-(self.speed-1),
                                           abs(worldrect.topleft[1])+self.rect.topright[1]+1))
                except:
                    print 'Couldnt get color 2'
                    color2 = (0,0,123,255)
                if color2 == (0,0,0,255):
                    self.rect = self.rect.move((0,1))
                else:
                    movingright = 0
            else:
                movingright = 0

            if movingleft == 0 and movingright == 0:
                moving = 0
            

    def check_floor(self,underlay,worldrect):
        try:
            color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomleft[0]+(self.speed-1),
                                   abs(worldrect.topleft[1])+self.rect.bottomleft[1]))
        except:
            color = (0,0,123,255)
        if color == (0,0,0,255):
            self.force_move_up(underlay,worldrect)
            self.falling_speed = 0
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0

        try:
            color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomright[0]-(self.speed-1),
                                   abs(worldrect.topleft[1])+self.rect.bottomright[1]))
        except:
            color = (0,0,123,255)
        if color == (0,0,0,255):
            self.force_move_up(underlay,worldrect)
            self.falling_speed = 0
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0
        
        return 1

    def force_move_up(self,underlay,worldrect):
        moving = 1
        movingleft = 1
        movingright = 1
        while moving==1:
            try:
                color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomleft[0]+(self.speed-1),
                                       abs(worldrect.topleft[1])+self.rect.bottomleft[1]))
            except:
                color = (0,0,123,0)
            if color == (0,0,0,255):
                try:
                    color2=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomleft[0]+(self.speed-1),
                                           abs(worldrect.topleft[1])+self.rect.bottomleft[1]-1))
                except:
                    color2 = (0,0,123,0)
                if color2 == (0,0,0,255):
                    self.rect = self.rect.move((0,-1))
                else:
                    movingleft = 0
            else:
                movingleft = 0

                
            try:
                color=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomright[0]-(self.speed-1),
                                       abs(worldrect.topleft[1])+self.rect.bottomright[1]))
            except:
                color = (0,0,123,0)
            if color == (0,0,0,255):
                try:
                    color2=underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomright[0]-(self.speed-1),
                                           abs(worldrect.topleft[1])+self.rect.bottomright[1]-1))
                except:
                    color2 = (0,0,123,0)
                if color2 == (0,0,0,255):
                    self.rect = self.rect.move((0,-1))
                else:
                    movingright = 0
            else:
                movingright = 0

            if movingleft == 0 and movingright == 0:
                moving = 0

    def move_left(self,underlay,worldrect):
        move = (0,0)
        if self.check_move_left(underlay,worldrect) == 1:
            move = (-self.speed,0)

        self.rect = self.rect.move(move)

    def check_move_left(self,underlay,worldrect):
        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomleft[0]-self.speed+2,
                                    abs(worldrect.topleft[1])+self.rect.bottomleft[1]-4))
        except:
            color = (0,0,123,255)
        if color == (0,0,0):
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0

        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.topleft[0]-self.speed+2,
                                    abs(worldrect.topleft[1])+self.rect.topleft[1]+4))
        except:
            color = (0,0,123,255)
        if color == (0,0,0):
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0

        return 1

    def move_right(self,underlay,worldrect):
        move = (0,0)
        if self.check_move_right(underlay,worldrect) == 1:
            move = (self.speed,0)

        self.rect = self.rect.move(move)

    def check_move_right(self,underlay,worldrect):
        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.bottomright[0]+self.speed-2,
                                    abs(worldrect.topleft[1])+self.rect.bottomright[1]-4))
        except:
            color = (0,0,123,255)
        if color == (0,0,0):
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0

        try:
            color = underlay.get_at((abs(worldrect.topleft[0])+self.rect.topright[0]+self.speed-2,
                                    abs(worldrect.topleft[1])+self.rect.topright[1]+4))
        except:
            color = (0,0,123,255)
        if color == (0,0,0):
            return 0
        if color == (255,0,0,255):
            self.die()
            return 0

        return 1
            
    def jump(self,underlay,worldrect):
        self.falling_speed = -(self.jump_force)
        move = (0,self.falling_speed)
        self.rect=self.rect.move(move)

    def power_jump(self,underlay,worldrect):
        self.falling_speed = -(self.jump_force)
        move = (0,self.falling_speed)
        self.rect=self.rect.move(move)

    def die(self):
        self.alive = 0

    def move(self,move):
        self.rect = self.rect.move(move)

    def world_moves(self,move):
        self.rect = self.rect.move(move)
        for particle in self.particles:
            particle.move(move)
